import { Mesh, MeshBasicMaterial, LinearFilter, Texture, PlaneGeometry } from "three";
import GeoUtils from "../../utils/GeoUtils";
import Helper from "../../utils/Helper";
import { App } from "../../Engine";
import TilePort from "../../component/models/TilePort";
import MeshUtil from "../../renderExtension/utils/MeshUtil";
import Events from "../../application/constants/Events";
import ParseBundleTile from "../utils/ParseBundleTile";
import { CustomMeshBasicMaterial } from "../../renderExtension/Material/CustomMaterial";
/**
 * 基础瓦片
 */
export default class WMSTile extends Mesh implements TilePort{    
    protected wmsUrl: string;
    protected options: any;
    protected callbackLoadSuccess;
    public material: CustomMeshBasicMaterial;
    private imageRequest;
    private static defaultTexture: Texture; //默认的纹理
    private static tileGeometry: PlaneGeometry;
    private lrc;

    /**
     * 基础瓦片的构造函数
     * @param options 构造函数的参数
     * options.wmsUrl 影像底图的url
     * options.urlDecimal 影像底图url中的瓦片行列号是否是十进制，true表示十进制，false表示十六进制
     * options.demUrl dem底图的url
     * options.demUrlDecimal dem底图url中的瓦片行列号是否是十进制，true表示十进制，false表示十六进制
     * options.demScale dem高度的夸张值
     * options.demHeightAdjust 一个高度值，用于调整dem底图的高度
     * options.useDefaultTexture 是否使用默认瓦片底图，当瓦片的影像纹理请求还没有成功的时候，瓦片先使用默认瓦片底图
     * options.loaded 纹理图片加载成功后的回调函数
     * options.curzoom 当前地图的层级
     * options.lrc 瓦片行列号的json数据
     * options.zIndex 为了避免深度冲突，调整高度值
     * 
     */
    constructor(options: any) {
        super(undefined, undefined);
        this.options = options;
        this.callbackLoadSuccess = options.loaded;

        this.setTile(options);
        this.setGeometry(options);
        this.setMaterial(options);
        
        Helper.enablePolygonOffset(this.material, App.getInstance().options.Map.maxZoom - this.lrc.z, options.zIndex);
    }

    private setTile(options){
        this.lrc = options.lrc;
        let lrc = this.lrc;
        let cx = GeoUtils.getCDevX(lrc.x, lrc.z, 0.5);
        let cy = GeoUtils.getRDevY(lrc.y, lrc.z, 0.5);
        this.position.set(cx, cy, 0);
        this.wmsUrl = Helper.getTileUrl(this.options.wmsUrl, lrc.x, lrc.y, lrc.z, (this.options.wmsUrlDecimal === undefined) ? true : this.options.wmsUrlDecimal);//options.wmsUrl;
    }

    private setGeometry(options){
        let tileWidth = GeoUtils.getTileWidth(options.curzoom);
        this.geometry = new PlaneGeometry(tileWidth, tileWidth, 10, 10);

        if (!WMSTile.tileGeometry || WMSTile.tileGeometry['tileWidth'] != tileWidth) { //一个层级只使用一个几何体
            WMSTile.tileGeometry = new PlaneGeometry(tileWidth, tileWidth, 1, 1);
            WMSTile.tileGeometry['tileWidth'] = tileWidth;
        }
        this.geometry = WMSTile.tileGeometry;
    }

    public updateVisibility(){
        this.visible = false;
    }

    public restoreVisibility(){
        this.visible = true;
    }

    private setMaterial(options){
        let materialParam = {
            coreParameters: {
                // depthTest: true,
                transparent: true,
                // opacity: 0,
            },
            identity: 'wmsTileMaterial'
        };

        this.material = new CustomMeshBasicMaterial(materialParam); //CustomMeshBasicMaterial
        this.material.visible = false;
        this.material.needsUpdate = true;

        this.requestWMS(this.wmsUrl);
    }

    private requestWMS(wmsUrl) {
        if (!wmsUrl) return;

        let parseBundle:ParseBundleTile = this.options['parseBundle'];
        if (!parseBundle) { //松散型瓦片
            let imageTexture = Helper.createTexture(wmsUrl, this.callbackTexture.bind(this), true);
            this.imageRequest = imageTexture['imageLoader'];
        }else{ //紧凑型瓦片
            let self = this;
            parseBundle.getTile(this.options.lrc.x, this.options.lrc.y, this.options.lrc.z, function (imageData) {
                let imageTexture = Helper.createTextureWithData(imageData, self.callbackTexture.bind(self));
                self.imageRequest = imageTexture['imageLoader'];
            });
        }

       
    }

    private callbackTexture(isSuccess, texture){
        if (isSuccess) {
            this.visible = true;
            texture.magFilter = LinearFilter;
            texture.minFilter = LinearFilter;
            this.material.map = texture;
            // scope.material.opacity = 1;
            this.material.visible = true;
            this.material.transparent = true;
            this.material.needsUpdate = true;
            // scope.material.depthTest = false;
            if (this.callbackLoadSuccess instanceof Function){
                this.callbackLoadSuccess(this);
            }

            this.imageRequest = null;
        }else{
            this.parent.remove(this);
            this.dispose();
        }
        App.getInstance().fireEvent(Events.AddTile); //添加了新的瓦片，对外广播通知
    }

    public cancleNetTask(){
        if (this.imageRequest) {
            if(this.imageRequest instanceof XMLHttpRequest){
                this.imageRequest.abort();
                this.imageRequest.onload = null;
                this.imageRequest.onerror = null;
            }else{
                 this.imageRequest.src = '';
            }
        }
    }

    public dispose() {
        this.cancleNetTask();
        MeshUtil.dispose(this);
    }

    public setCut(clapData: {isOpenClap: boolean, clapPointArray: [], clapPointCount: number, renderSide: number}) {
        this.material['setCut'](clapData);
    }
}